package com.study.streamApi;

import com.alibaba.fastjson.JSON;
import com.study.collectors.Bean.People;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Stream流分组排序
 *
 * @author yangyanbin
 * @since 20221104
 **/
public class StreamMapSorted {
    public static void main(String[] args) {

        //0、 生成乱序的People对象列表（初始化数据）
        List<People> randomPeopleList = StreamMapSorted.randomPeopleList(10);
        for (People people : randomPeopleList) {
            System.err.println(people);
        }

        // 1、country分组
        Map<String, List<People>> countryGroupMap = randomPeopleList.stream().collect(Collectors.groupingBy(People::getCountry));
        for (String key : countryGroupMap.keySet()) {
            System.out.println("key = " + key + "\n" + "value=" + countryGroupMap.get(key));
        }

        // 2、country分组每组取一条
        Map<String, People> countryGroupGetOneMap = randomPeopleList.stream()
                .collect(Collectors.groupingBy(People::getCountry, Collectors.collectingAndThen(Collectors.reducing((x1, x2) -> x1), Optional::get)));
        System.err.println("countryGroupGetOneMap = " + countryGroupGetOneMap);


        // 3、对分组后（每组取一条）的map根据nationalDay倒序（nationalDay可能为空null放最后）
        Map<String, People> linkedHashMap = new LinkedHashMap<>();
        countryGroupGetOneMap.entrySet().stream()
                .sorted(Map.Entry.<String, People>comparingByValue(
                        Comparator.comparing(People::getNationalDay, Comparator.nullsFirst(Date::compareTo))
                ).reversed())
                .forEachOrdered(entry -> linkedHashMap.put(entry.getKey(), entry.getValue()));
        System.err.println("linkedHashMap = " + linkedHashMap);


        // 4、获取根据 nationalDay 排序后的 country列表(keys)
        List<String> nationalDaySortCountryGroupCountryList = new ArrayList<String>(linkedHashMap.keySet());
        System.err.println("nationalDaySortCountryGroupCountryList = " + nationalDaySortCountryGroupCountryList);


        // 5、根据country（keys）列表 获取完整分组、排序、排序类表（每组再根据年龄升序）
        List<People> finalPeopleGroupSortList = new ArrayList<>();
        for (String country : nationalDaySortCountryGroupCountryList) {
            List<People> ageSortGroup = countryGroupMap.get(country).stream().sorted(Comparator.comparing(People::getAge)).collect(Collectors.toList());
            finalPeopleGroupSortList.addAll(ageSortGroup);

        }
        for (People people : finalPeopleGroupSortList) {
            System.err.println("people = " + people);
        }

        // 1、先按NationalDay倒序排列（nationalDay属性为空放最后），相同时按照age升序
        List<People> reversedNationalDayThenSortedAge = randomPeopleList.stream().sorted(Comparator.comparing(People::getNationalDay,
                Comparator.nullsFirst(Date::compareTo)).reversed().thenComparing(People::getAge)).collect(Collectors.toList());

        for (People people : reversedNationalDayThenSortedAge) {
            System.out.println("people = " + people);
        }
        // 2、底层使用的是无序的HashMap
        Map<String, List<People>> countryGroupMapSort =
                reversedNationalDayThenSortedAge.stream().collect(Collectors.groupingBy(People::getCountry));
        for (String key : countryGroupMapSort.keySet()) {
            System.out.println("key = " + key + "\n" + "valueSort=" + countryGroupMap.get(key));
        }

        // 2、使用LinkHashMap让其map有序
        Map<String, List<People>> listLinkedHashMap = reversedNationalDayThenSortedAge.stream().collect(Collectors.groupingBy(People::getCountry, LinkedHashMap::new
                , Collectors.toList()));
        System.out.println(JSON.toJSON(listLinkedHashMap));
        for (String key : countryGroupMapSort.keySet()) {
            System.out.println("key = " + key + "\n" + "valueSort=" + countryGroupMap.get(key));
        }


    }

    // 生成乱序的People对象
    public static List<People> randomPeopleList(int size) {
        List<People> list = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            People people = new People();
            people.setName("工具人" + i);
            int num = (int) (Math.random() * 10 % 5);
            people.setAge(20 + (int) (Math.random() * 10 % 9));
            switch (num) {
                case 0:
                    people.setCountry("China");
                    people.setNationalDay(parserDate("1949-10-01 00:00:00"));
                    break;
                case 1:
                    people.setCountry("Japan");
                    people.setNationalDay(null);
                    break;
                case 2:
                    people.setCountry("U.S");
                    people.setNationalDay(parserDate("1776-07-04 00:00:00"));
                    break;
                case 3:
                    people.setCountry("Korea");
                    people.setNationalDay(parserDate("1948-08-15 00:00:00"));
                    break;
                case 4:
                    people.setCountry("Egypt");
                    people.setNationalDay(parserDate("1952-07-23 00:00:00"));
                    break;
                default:
                    ;
            }
            list.add(people);
        }
        return list;
    }

    /**
     * @Description: 字符串解析为日期
     * @Param:
     * @return:
     */
    public static Date parserDate(String dateStr) {
        Date date = null;
        try {
            date = new SimpleDateFormat("yyy-MM-dd HH:mm:mm").parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


}
